#include "Dijkstra.h"
#include "Init.h"
#include "queue"
#include"QColor"
#include<QGraphicsView>
#include"ZoomIO.h"
#include<QMessageBox>
#include<QStack>
#include<QGraphicsLineItem>
/*
extern QMap<QString,node> Station; //画图使用
extern QMap<QString,QList<QString> > edge; // 跑最短路
extern QMap<QString,QSet<QString> > Station_Line; // 站点所属线路总
extern QMap<QString,QColor> LineColor;  //  线路颜色
extern QMap<QString,QMap<QString,int> >dp; //两站点之间的距离；
extern QMap<QString,QMap<QString,QSet<QString> > >mp; //两站站点共同的线路
*/

void ChooseShortorLessPath(QGraphicsView *graphicsView,QString startstr,QString endstr,QRadioButton *sht,QRadioButton *less,QTextBrowser *textBrowser){
    qDebug()<<"选择开始\n";
    if(startstr.size()==0||endstr.size()==0){
        QMessageBox MyBox(QMessageBox::Warning,"警告","请选择站点",QMessageBox::Yes|QMessageBox::No);
        MyBox.exec();
        return;
    }
    QMap<QString, node>::iterator it = Station.find(startstr);
    if (it == Station.end()) {
        QMessageBox MyBox(QMessageBox::Warning,"警告","输入站点有误",QMessageBox::Yes|QMessageBox::No);
        MyBox.exec();
        return;
    }
    it =Station.find(endstr);
    if (it == Station.end()) {
        QMessageBox MyBox(QMessageBox::Warning,"警告","输入站点有误",QMessageBox::Yes|QMessageBox::No);
        MyBox.exec();
        return;
    }
    if(startstr == endstr){
        QMessageBox MyBox(QMessageBox::Warning,"警告","请不要输入相同站点 ",QMessageBox::Yes|QMessageBox::No);
        MyBox.exec();
        return;
    }

    if(sht->isChecked()) getshortTimePath(graphicsView,startstr,endstr,textBrowser);
    if(less->isChecked()) getlessTransPath(graphicsView,startstr,endstr,textBrowser);

}

//dist trans node
typedef std::pair<int,int> PII;
typedef std::pair<QString,QString> nodea;
typedef std::pair<PII,nodea> PLL;

void getshortTimePath(QGraphicsView *graphicsView,const QString startstr,const QString endstr,QTextBrowser *textBrowser){
    qDebug()<<"选择成功\n";
    const int IntMax = INT32_MAX;
    QMap<QString,int> dist; //距离表
    QMap<QString,int> trans; //换乘
    QMap<nodea,bool> final; //是否遍历过


    for(auto i:Station.keys()){
        dist[i] = IntMax;
        trans[i] = IntMax;
    }


    QMap<QString,nodea>pre;
    pre[startstr] = nodea{"00","00"};
    std::priority_queue<PLL,std::vector<PLL >, std::greater<PLL > > q;
    for(auto i:Station_Line[startstr]){
        q.push(PLL{{0,0},nodea{startstr,i}});

    }
    dist[startstr] = 0;
    trans[startstr] = 0;
    qDebug()<<"初始化完成\n";

    while(q.size()){
        PLL f= q.top();
        q.pop();
        nodea now = f.second;
        if(final[now]) continue;
        final[now] = true;

        for(auto i:edge[now.first]){ //相邻的站点
            for(auto j:mp[now.first][i]){ //和相邻站点共有的线路

               qDebug()<<now.first<<"-----"<<i<<"----"<<j<<" \n ";
                nodea newnodea = nodea{i,j};
               if(final[newnodea]) continue;
                if(dist[i] > dist[i]+dp[now.first][i]){
                    dist[i] = dist[i]+dp[now.first][i];
                    qDebug()<<now.first<<"---"<<i<<"......."<<dist[i]<<" \n ";
                    if(j == now.second){ trans[i] = trans[now.first];  pre[i] = now; }
                    else {trans[i] = trans[now.first] + 1; pre[i] = nodea{now.first,j}; }

                    qDebug()<<i<<"---"<<pre[i]<<" \n ";
                    q.push(PLL{PII{dist[i],trans[i]},newnodea});

                }else if(dist[i] == dist[now.first]+dp[now.first][i]){
                    if(j == now.second){
                        if(trans[i] > trans[now.first]){
                              trans[i] = trans[now.first];
                              pre[i] = now;
                              q.push(PLL{PII{dist[i],trans[i]},newnodea});
                        }
                    }
                    if(j != now.second){
                        if(trans[i] > trans[now.first] + 1 ){
                              trans[i] = trans[now.first] + 1;
                              pre[i] = nodea{now.first,j};
                              q.push(PLL{PII{dist[i],trans[i]},newnodea});
                        }
                    }
                }
            }
        }
    }
    qDebug()<<"最短路执行完毕\n";
    QList<nodea>s;
    int t=0;
    nodea u = pre[endstr];
    while(u.second!="00"){
        s.append(u);
        qDebug()<<"---"<<u.first<<" \n ";
        u=pre[u.first];
        t++;
        if(t>40) return;
    }
    qDebug()<<"还原成功\n";
    drawpath(graphicsView,startstr,endstr,s,textBrowser);
}

void getlessTransPath(QGraphicsView *graphicsView ,const QString startstr,const QString endstr,QTextBrowser *textBrowser){
    qDebug()<<"选择成功\n";
    const int IntMax = INT32_MAX;
    QMap<QString,int> dist; //距离表
    QMap<QString,int> trans; //换乘
    QMap<nodea,bool> final; //是否遍历过


    for(auto i:Station.keys()){
        trans[i] = IntMax;
        dist[i] = IntMax;
    }


    QMap<QString,nodea>pre;
    pre[startstr] = nodea{"00","00"};
    std::priority_queue<PLL,std::vector<PLL >, std::greater<PLL > > q;
    for(auto i:Station_Line[startstr]){
        q.push(PLL{{0,0},nodea{startstr,i}});
    }
    dist[startstr] = 0;
    trans[startstr] = 0;
    qDebug()<<"初始化完成\n";

    while(q.size()){
        PLL f= q.top();
        q.pop();
        nodea now = f.second;
        if(final[now]) continue;
        final[now] = true;

        for(auto i:edge[now.first]){ //相邻的站点
            for(auto j:mp[now.first][i]){ //和相邻站点共有的线路

                qDebug()<<now.first<<"-----"<<i<<"----"<<j<<" \n ";
                nodea newnodea = nodea{i,j};
                if(final[newnodea]) continue;

                    if(j == now.second){
                        if(trans[i] > trans[now.first]){
                              dist[i] = dist[now.first] + dp[now.first][i];
                              trans[i] = trans[now.first];
                              pre[i] = now;
                              q.push(PLL{PII{trans[i],dist[i]},newnodea});
                              qDebug()<<now.first<<"---"<<i<<"......."<<dist[i]<<" \n ";
                        }else if(trans[i] == trans[now.first]){
                              if(dist[i] > dist[now.first]+dp[now.first][i]){
                              dist[i] = dist[now.first]+dp[now.first][i];
                              qDebug()<<now.first<<"---"<<i<<"......."<<dist[i]<<" \n ";
                              pre[i] = now;
                              q.push(PLL{PII{trans[i],dist[i]},newnodea});
                              }
                        }
                    }
                    if(j != now.second){
                        if(trans[i] > trans[now.first] + 1 ){
                              trans[i] = trans[now.first] + 1;
                              dist[i] = dist[now.first] + dp[now.first][i];
                              pre[i] = nodea{now.first,j};
                              q.push(PLL{PII{trans[i],dist[i]},newnodea});
                              qDebug()<<now.first<<"---"<<i<<"......."<<now<<" \n ";
                        }else if(trans[i] == trans[now.first] + 1 ){
                              if(dist[i] > dist[now.first]+dp[now.first][i]){
                              dist[i] = dist[now.first]+dp[now.first][i];
                              qDebug()<<now.first<<"---"<<i<<"......."<<dist[i]<<" \n ";
                              pre[i] = nodea{now.first,j};
                              q.push(PLL{PII{trans[i],dist[i]},newnodea});
                              }
                        }
                    }

            }
        }
    }
    qDebug()<<"最短路执行完毕\n";
    QList<nodea>s;
    int t=0;
    nodea u = pre[endstr];
    while(u.second!="00"){
        s.append(u);
        qDebug()<<"---"<<u.first<<" \n ";
        u=pre[u.first];
        t++;
        if(t>40) return;
    }
    qDebug()<<"还原成功\n";
    drawpath(graphicsView,startstr,endstr,s,textBrowser);
}


void drawpath(QGraphicsView *graphicsView,const QString startstr,const QString endstr,QList<std::pair<QString,QString>>path,QTextBrowser *textBrowser){

    qDebug()<<"开始画图\n";
    QGraphicsScene *scene;   //绘图场景
    scene = new QGraphicsScene;
    scene->setBackgroundBrush(Qt::white);
    scene->setSceneRect(0,0,1500,1000);// f分辨率
    qDebug()<<"传参成功";
    graphicsView->setRenderHint(QPainter::Antialiasing);
    graphicsView->setScene(scene);
    graphicsView->setDragMode(QGraphicsView::ScrollHandDrag);

    scene->clear();
    refresh(graphicsView);
    textBrowser->clear();
    QString sp[200];
    QString pp[200];
    int cnt=0;
    int ans=0;
    sp[++cnt] = endstr;
    qDebug()<<endstr<<"\n";
    for(auto i:path){
        sp[++cnt] = i.first;
        pp[++ans] = i.second;
        qDebug()<<sp[cnt]<<"\n";
    }
    ans++;
    pp[ans] = pp[ans-1];
    //draw line first
    for(int i=1;i<cnt;i++){
        QGraphicsLineItem *line = new QGraphicsLineItem();
        QPointF pos1,pos2;
        pos1.setX(Station[sp[i]].coord.x()+3);
        pos1.setY(Station[sp[i]].coord.y()+3);
        pos2.setX(Station[sp[i+1]].coord.x()+3);
        pos2.setY(Station[sp[i+1]].coord.y()+3);
        line->setLine(QLineF(pos1,pos2));
        line->setPen(QPen(LineColor[pp[i]]));
        scene->addItem(line);
    }

    for(int i=1;i<=cnt;i++){
        QPen elli_pen;
        elli_pen.setColor(LineColor[pp[i]]);
        QGraphicsEllipseItem *elli = new QGraphicsEllipseItem();

        elli->setRect(QRect(Station[sp[i]].coord.x(),Station[sp[i]].coord.y(),6,6));

        qDebug()<<Station[sp[i]].coord.x()<<" "<<Station[sp[i]].coord.y()<<"\n";
     //   qDebug()<<*Station_Line[sp[i]].begin()<<" "<<LineColor[*Station_Line[i].begin()]<<" \n";

        elli->setPen(elli_pen);

        elli->setBrush(Qt::white);
        /*
        在这段代码中，您设置了两个颜色：一个是 QPen 的颜色，另一个是 QBrush 的颜色
        QPen 用于绘制形状的边框，而 QBrush 用于绘制形状的填充颜色.
        */
        //Latitude and longitude）即经线和纬线
        QString info = "站点名称: "+sp[i]+"\n站点经纬度: "+
            QString::number(Station[sp[i]].e,'f',3)+
                       ","+QString::number(Station[sp[i]].n,'f',3);

        scene->addItem(elli);

        QGraphicsTextItem *text = new QGraphicsTextItem();
        text->setPlainText(sp[i]);
        text->setPos(Station[sp[i]].coord.x(),Station[sp[i]].coord.y()+1);
        text->setFont(QFont("consolas",4,1));
        text->setToolTip(info);
        scene->addItem(text);
    }

    textBrowser->setText("Co passage  " + QString::number(cnt) + "  stations");
    textBrowser->append("start to:" + startstr);
    textBrowser->append("        ↓take" + pp[cnt]);
    for(int i=cnt-1;i>1;i--){
        textBrowser->append("     "+sp[i]);
        if(pp[i] != pp[i-1]){
            textBrowser->append("       ↓transfer" + pp[i-1]);
        }else  textBrowser->append("       ↓");
    }
    textBrowser->append("End:  " + sp[1]);
    textBrowser->textCursor().setPosition(0);
    textBrowser->setTextCursor(textBrowser->textCursor());
}
